﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel.Dispatcher;
using System.ServiceModel;
using System.ServiceModel.Description;
using System.ServiceModel.Channels;

namespace WcfContrib.Extensions.Context
{
    internal class SessionContextExtension : IExtension<InstanceContext>
    {
        internal static SessionContextExtension Current
        {
            get
            {
                if (OperationContext.Current != null)
                {
                    return OperationContext.Current.InstanceContext.Extensions.Find<SessionContextExtension>();
                }

                return null;
            }
        }

        internal Dictionary<string, object> Items { get; set; }

        public SessionContextExtension()
        {
            Items = new Dictionary<string, object>();
        }

        public void Attach(InstanceContext owner)
        {
            
        }

        public void Detach(InstanceContext owner)
        {
        }
    }

    #region Initializer & Behavior
    internal class SessionContextExtensionInitializer : IInstanceContextInitializer
    {
        public void Initialize(InstanceContext instanceContext, Message message)
        {
            SessionContextExtension extension = new SessionContextExtension();
            instanceContext.Extensions.Add(extension);
        }
    }

    internal class SessionContextExtensionBehavior : IServiceBehavior, IEndpointBehavior
    {
        #region IServiceBehavior Members

        public void AddBindingParameters(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase, System.Collections.ObjectModel.Collection<ServiceEndpoint> endpoints, System.ServiceModel.Channels.BindingParameterCollection bindingParameters)
        {
        }

        public void ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
        {
            foreach (var ep in serviceDescription.Endpoints)
            {
                ep.Behaviors.Add(this);
            }
        }

        public void Validate(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
        {
        }

        #endregion

        #region IEndpointBehavior Members

        public void AddBindingParameters(ServiceEndpoint endpoint, System.ServiceModel.Channels.BindingParameterCollection bindingParameters)
        {
        }

        public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)
        {
        }

        public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher)
        {
            SessionContextExtensionInitializer extension = new SessionContextExtensionInitializer();
            endpointDispatcher.DispatchRuntime.InstanceContextInitializers.Add(extension);
        }

        public void Validate(ServiceEndpoint endpoint)
        {
        }

        #endregion
    }
    #endregion
}
